<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
    <title>Chapter 11: Joran</title>
    <link rel="stylesheet" type="text/css" href="../css/common.css" />
    <link rel="stylesheet" type="text/css" href="../css/screen.css" media="screen" />
    <link rel="stylesheet" type="text/css" href="../css/_print.css" media="print" />
    <link rel="stylesheet" type="text/css" href="../css/prettify.css" media="screen" />
  </head>
  <body  onload="prettyPrint(); decorate();">
    <script type="text/javascript">prefix='../'</script>
    <script type="text/javascript" src="../js/prettify.js"></script>
    <script type="text/javascript"> src="../templates/header.js"</script>
    <script type="text/javascript" src="../js/jquery-min.js"></script>
    <script type="text/javascript" src="../js/decorator.js"></script>

    <div id="left">
      <noscript>Please turn on Javascript to view this menu</noscript>
      <script src="../templates/left.js" type="text/javascript"></script>
    </div>
    <div id="right">
      <script src="menu.js" type="text/javascript"></script>
    </div>
    <div id="content">
      
    <h1>Chapter 11: Joran</h1>

    <a href="onJoran_ja.html">&#x548C;&#x8A33; (Japanese translation)</a>

    <div class="quote">
      <p><em>The answer, my friend, is blowin' in the wind, The answer
      is blowin' in the wind.</em></p>
      
      <p>&mdash;BOB DYLAN, <em>The Freewheelin' Bob Dylan</em></p>
    </div>

    <p class="big red">This chapter is outdated and needs to be
    re-written to account for the massive changes occuring in 1.3</p>
    
    <p>Joran stands for a cold north-west wind which, every now and
    then, blows forcefully on Lake Geneva. Located right in the middle
    of Western-Europe, the surface of Lake Geneva is smaller than many
    other European lakes. However, with its average depth of 153
    meters, it is unusually deep, and happens to be, by volume, the
    largest sweet water reserve in Western-Europe.
    </p>


    <p>As apparent in previous chapters, logback relies on Joran, a
    mature, flexible and powerful configuration framework. Many of the
    capabilities offered by logback modules are only possible on
    account of Joran. This chapter focuses on Joran, its basic design
    and its salient features.
    </p>

    <p>Joran is actually a generic configuration system which can be
    used independently of logging. To emphasize this point, we should
    mention that the logback-core module does not have a notion of
    loggers. In that spirit, most of the examples in this chapter have
    nothing to do with loggers, appenders or layouts.
    </p>

    <p>The examples presented in this chapter can be found under
    <em>LOGBACK_HOME/logback-examples/src/main/java/chapters/onJoran/</em>
    folder.
    </p>

    <p>To install Joran, simply <a
    href="../download.html">download</a> logback and add
    <em>logback-core-${project.version}.jar</em> to your
    classpath.</p>
    
    <h2 class="doAnchor">Historical perspective</h2>

    <p>Reflection is a powerful feature of the Java language, making
    it possible to configure software systems declaratively. For
    example, many important properties of an EJB are configured with
    the <em>ejb.xml</em> file. While EJBs are written in Java, many of
    their properties are specified within the <em>ejb.xml</em>
    file. Similarly, logback settings can be specified in a
    configuration file, expressed in XML format. Annotations available
    in JDK 1.5 and heavily used in EJB 3.0 replace many directives
    previously found in XML files. Joran also makes use of annotations
    but at a much smaller extent. Due to the dynamic nature of logback
    configuration data (compared to EJBs) Joran's use of annotations
    is rather limited.
    </p>

    <p>In log4j, logback's predecessor, the
    <code>DOMConfigurator</code> class, which is part of log4j version
    1.2.x and later, could also parse configuration files written in
    XML. <code>DOMConfigurator</code> was written in a way that forced
    us, the developers, to tweak the code each time the structure of
    the configuration file changed. The modified code had to be
    recompiled and redeployed. Just as importantly, the code of the
    <code>DOMConfigurator</code> consisted of loops dealing with
    child elements containing many interspersed if/else
    statements. One could not help but notice that this particular
    code reeked of redundancy and duplication.  The <a
    href="http://jakarta.apache.org/commons/digester/">commons-digester
    project</a> had shown us that it was possible to parse XML files
    using pattern matching rules. At parse time, digester would apply
    rules that matched designated patterns. Rule classes were usually
    quite small and specialized. Consequently, they were relatively
    easy to understand and maintain.
    </p>

    <p>Armed with the <code>DOMConfigurator</code> experience, we
    began developing <code>Joran</code>, a powerful configuration
    framework to be used in logback. Joran was largely inspired by the
    commons-digester project. Nevertheless, it uses a slightly
    different terminology. In commons-digester, a rule can be seen as
    consisting of a pattern and a rule, as shown by the
    <code>Digester.addRule(String pattern, Rule rule)</code>
    method. We find it unnecessarily confusing to have a rule to
    consist of itself, not recursively but with a different
    meaning. In Joran, a rule consists of a pattern and an action. An
    action is invoked when a match occurs for the corresponding
    pattern. This relation between patterns and actions lies at the
    core of Joran.  Quite remarkably, one can deal with quite complex
    requirements by using simple patterns, or more precisely with
    exact matches and wildcard matches.
    </p>

    <h3 class="doAnchor" name="saxOrDom">SAX or DOM?</h3>

    <p>Due to the event-based architecture of the SAX API, a tool based
    on SAX cannot easily deal with forward references, that is,
    references to elements which are defined later than the current
    element being processed. Elements with cyclical references are
    equally problematic. More generally, the DOM API allows the user to
    perform searches on all the elements and make forward jumps.
    </p>
    
    <p>This extra flexibility initially led us to choose the DOM API
    as the underlying parsing API for Joran. After some
    experimentation, it quickly became clear that dealing with jumps
    to distant elements while parsing the DOM tree did not make sense
    when the interpretation rules were expressed in the form of
    patterns and actions. <em>Joran only needs to be given the
    elements in the XML document in a sequential, depth-first
    order.</em>
    </p>

    <p>Moreover, the SAX API offers element location information which
    allows Joran to display the exact line and column number where an
    error occurred. Location information comes in very handy in the
    identification of parsing problems.
    </p>
    
    <h3>Non goals</h3>

    <p>Given its highly dynamic nature, the Joran API is not intended
    to be used to parse very large XML documents with many thousands
    of elements.
    </p>


    <h3 class="doAnchor" name="pattern">Pattern</h3>

    <p>A Joran pattern is essentially a string. There are two kind of
    patterns, <em>exact</em> and <em>wildcard</em>. The pattern "a/b"
    can be used to match a <code>&lt;b></code> element nested within a
    top-level <code>&lt;a></code> element. The "a/b" pattern will not match
    any other element, hence the <em>exact</em> match designation.</p>

    <p>Wildcards can be used to match suffixes or prefixes. For
    example, the "*/a" pattern can be used to match any suffix ending
    with "a", that is any <code>&lt;a></code> element within an XML
    document but not any elements nested within <code>&lt;a></code>.
    The "a/*" pattern will match any element prefixed by
    <code>&lt;a></code>, that is any element nested within an
    <code>&lt;a></code> element.
    </p>

    <h3 class="doAnchor" name="action">Actions</h3>
    
    <p>As mentioned above, Joran parsing rules consists of the
    association of patterns. Actions extend the <a
    href="../xref/ch/qos/logback/core/joran/action/Action.html"><code>Action</code></a>
    class, consisting of the following abstract methods. Other methods
    have been omitted for brevity.
    </p>


    <pre class="prettyprint source">package ch.qos.logback.core.joran.action;

import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import ch.qos.logback.core.joran.spi.InterpretationContext;

public abstract class Action extends ContextAwareBase {
  /**
   * Called when the parser encounters an element matching a
   * {@link ch.qos.logback.core.joran.spi.Pattern Pattern}.
   */
  public abstract void begin(InterpretationContext ic, String name,
      Attributes attributes) throws ActionException;

  /**
   * Called to pass the body (as text) contained within an element.
   */
  public void body(InterpretationContext ic, String body)
      throws ActionException {
    // NOP
  }

  /*
   * Called when the parser encounters an endElement event matching a
   * {@link ch.qos.logback.core.joran.spi.Pattern Pattern}.
   */
  public abstract void end(InterpretationContext ic, String name)
      throws ActionException;
}</pre>

   <p>Thus, every action must implement the <code>begin()</code> and
   <code>end()</code> methods. The implementation of the
   <code>body()</code> method is optional on account of the
   empty/nop implementation provided by <code>Action</code>.</p>


   <h3 class="doAnchor" name="ruleStore">RuleStore </h3>

   <p>As mentioned previously, the invocation of actions according to
   matching patterns is a central concept in Joran. A rule is an
   association of a pattern and an action. Rules are stored in a <a
   href="../xref/ch/qos/logback/core/joran/spi/RuleStore.html">RuleStore</a>.   
   </p>

   <p>As mentioned above, Joran is built on top of the SAX API. As an
   XML document is parsed, each element generates events corresponding
   to the start, body and end of each element. When a Joran
   configurator receives these events, it will attempt to find in its
   rule store an action corresponding to the <em>current
   pattern</em>. For example, the current pattern for the start, body
   or end event of element <em>B</em> nested within a top-level
   <em>A</em> element is "A/B".  The current pattern is a data
   structure maintained automatically by Joran as it receives and
   processes SAX events. </p>

   <p>When several rules match the current pattern, then exact
   matches override suffix matches, and suffix matches override prefix
   matches. For exact details of the implementation, please see the <a
   href="../xref/ch/qos/logback/core/joran/spi/SimpleRuleStore.html">SimpleRuleStore</a>
   class.
   </p>
   

   <h3 class="doAnchor" name="interpretationContext">Interpretation
   context</h3>

   <p>To allow various actions to collaborate, the invocation of begin
   and end methods include an interpretation context as the first
   parameter. The interpretation context includes an object stack, an
   object map, an error list and a reference to the Joran interpreter
   invoking the action. Please see the <a
   href="../xref/ch/qos/logback/core/joran/spi/InterpretationContext.html"><code>InterpretationContext</code></a>
   class for the exact list of fields contained in the interpretation
   context.
   </p>
   
   <p>Actions can collaborate together by fetching, pushing or popping
   objects from the common object stack, or by putting and fetching
   keyed objects on the common object map. Actions can report any error
   conditions by adding error items on the interpretation context's
   <code>StatusManager</code>.
   </p>
   
   <h3 class="doAnchor" name="helloWorld">Hello world</h3>
   
   <p>The first example in this chapter illustrates the minimal
   plumbing required for using Joran. The example consists of a
   trivial action called <a
   href="../xref/chapters/onJoran/helloWorld/HelloWorldAction.html">
   <code>HelloWorldAction</code></a> which prints "Hello World" on the
   console when its <code>begin()</code> method is invoked. The
   parsing of XML files is done by a configurator. For the purposes of
   this chapter, we have developed a very simple configurator called
   <a
   href="../xref/chapters/onJoran/SimpleConfigurator.html"><code>SimpleConfigurator</code></a>.
   The <a
   href="../xref/chapters/onJoran/helloWorld/HelloWorld.html"><code>HelloWorld</code></a>
   application brings all these pieces together:
   </p>

   <ul>
     <li>It creates a map of rules and a <code>Context</code></li>
     <li>It creates a parsing rule by associating the
     <em>hello-world</em> pattern with a corresponding
     <code>HelloWorldAction</code> instance</li>
     <li>It creates a <code>SimpleConfigutator</code>, passing it the
     aforementioned rules map</li>
     <li>It then invokes the <code>doConfigure</code> method of the
     configurator, passing the designated XML file as parameter
     </li>
     <li>As a last step, the accumulated Status message in the context,
     if any, are printed</li>
   </ul>

    <p>The <em>hello.xml</em> file contains one &lt;hello-world&gt;
    element, without any other nested elements. See the
    <em>logback-examples/src/main/java/chapters/onJoran/helloWorld/</em>
    folder for exact contents.
    </p>
 
    <p>Running the HelloWorld application with <em>hello.xml</em> file
    will print "Hello World" on the console.</p>
   
    <p class="command">java chapters.onJoran.helloWorld.HelloWorld src/main/java/chapters/onJoran/helloWorld/hello.xml</p>

    <p>You are highly encouraged to poke about in this example, by adding
    new rules on the rule store, modifying the XML document
    (hello.xml) and adding new actions.
    </p>

    <!-- ====================================================== -->

    <h3 class="doAnchor" name="calculator">Collaborating actions</h3>
   
    <p>The <em>logback-examples/src/main/java/joran/calculator/</em>
    directory includes several actions which collaborate together
    through the common object stack in order to accomplish simple
    computations.
    </p>

    <p>The <em>calculator1.xml</em> file contains a
    <code>computation</code> element, with a nested
    <code>literal</code> element. Here are its contents.
    </p>

    <em>Example 10.<span class="autoEx"/>: First calculator example
    (logback-examples/src/main/java/chapters/onJoran/calculator/calculator1.xml)</em>

    <em> </em>
    <pre class="prettyprint source">&lt;computation name="total">
  &lt;literal value="3"/>
&lt;/computation></pre>

    <p>In the <a href="../xref/chapters/onJoran/calculator/Calculator1.html">
    <code>Calculator1</code></a> application, we declare various
    parsing rules (patterns and actions) collaborating together to
    compute a result based on the contents of an XML document. 
    </p>

    <p> Running <code>Calculator1</code> application with
    <em>calculator1.xml</em></p>

    <p class="command">java chapters.onJoran.calculator.Calculator1 src/main/java/chapters/onJoran/calculator/calculator1.xml</p>

    <p>will print:</p>

    <p class="console">The computation named [total] resulted in the value 3</p>


    <p>Parsing the <em>calculator1.xml</em> document (listed above)
    involves the following steps:
    </p>

    <ul>
      <li>The start event corresponding to the &lt;computation&gt;
      element translates into the current pattern
      "/computation". Since in the <a
      href="../xref/chapters/onJoran/calculator/Calculator1.html">
      <code>Calculator1</code></a> application we associated the
      pattern "/computation" with a
      <a
      href="../xref/chapters/onJoran/calculator/ComputationAction1.html">
      <code>ComputationAction1</code></a> instance, the
      <code>begin()</code> method of that
      <code>ComputationAction1</code> instance is invoked.
      </li>

      <li><p>The start event corresponding to the &lt;literal&gt;
      element translates into the current pattern
      "/computation/literal". Given the association of the
      "/computation/literal" pattern with a
      <a
      href="../xref/chapters/onJoran/calculator/LiteralAction.html">
      <code>LiteralAction</code></a> instance, the
      <code>begin()</code> method of that <code>LiteralAction</code>
      instance is called.</p>
      </li>

      <li><p>By the same token, the end event corresponding to the
      &lt;literal&gt; element triggers the invocation of the
      <code>end</code>() method of the same <code>LiteralAction</code>
      instance.</p>
      </li>


      <li><p>Similarly, the event corresponding to the end of
      &lt;computation&gt; element triggers the invocation the
      <code>end()</code> method of the <code>ComputationAction1</code>
      same instance.
      </p>
      </li>
    </ul>

    <p>What is interesting here is the way actions collaborate.  The
    <code>LiteralAction</code> reads a literal value and pushes it in
    the object stack maintained by the
    <code>InterpretationContext</code>. Once done, any other action
    can pop the value to read or modify it. Here, the
    <code>end()</code> method of the <code>ComputationAction1</code>
    class pops the value from the stack and prints it.
    </p>

    <!-- TO BE CONTINUED -->

    <p>The next example, <em>calculator2.xml</em> file is a bit more
    complex, but also more interesting.</p>

    <em>Example 10.<span class="autoEx"/>: Calculator configuration
    file
    (logback-examples/src/main/java/chapters/onJoran/calculator/calculator2.xml)</em>
  <pre class="prettyprint source">&lt;computation name="toto"&gt;
  &lt;literal value="7"/&gt;
  &lt;literal value="3"/&gt;
  &lt;add/&gt;
  &lt;literal value="3"/&gt;
  &lt;multiply/&gt;
&lt;/computation&gt;</pre>


  <p>As in the previous example, in response to the &lt;literal&gt;
  element,the appropriate <a
  href="../xref/chapters/onJoran/calculator/LiteralAction.html">
  <code>LiteralAction</code></a> instance will push an integer,
  corresponding to the value attribute, at the top of the
  interpretation context's object stack. In this example, that is
  <em>calculator2.xml</em>, the values are 7 and 3. In response to the
  &lt;add&gt; element, the appropriate <a
  href="../xref/chapters/onJoran/calculator/AddAction.html"><code>AddAction</code></a>
  will pop two previously pushed integers, compute their sum and push
  the result, i.e. 10 (=7+3), at the top of the interpretation
  context's stack. The next literal element will cause LiteralAction
  to push an integer with value 3 at the top of the stack. In response
  to the &lt;multiply&gt; element, the appropriate <a
  href="../xref/chapters/onJoran/calculator/MultiplyAction.html"><code>MultiplyAction</code></a>
  will pop two previously pushed integers, i.e. 10 and 3, and compute
  their product.  It will push the result, i.e. 30, at the top of the
  stack. At the very end, in reponse to the end event corresponding to
  the &lt;/computation&gt; tag, the ComputationAction1 will print the
  object at the top of the stack. Thus, running:
  </p>

  <p class="command">java chapters.onJoran.calculator.Calculator1 src/main/java/chapters/onJoran/calculator/calculator2.xml </p>
  
  <p>will yield</p>

  <p class="console">The computation named [toto] resulted in the value 30 </p>
  

  <!--


  <p>Finally, a <em>calculator3.xml</em> is also provided, to
  demonstrate the possibility elements that contain instances of the
  same element. Here's the content of <em>calculator3.xml</em>:</p>

  <em>Example 10.<span class="autoEx"/>: Calculator configuration file
  (logback-examples/src/main/java/chapters/onJoran/calculator/calculator3.xml)</em>

<pre class="prettyprint source">&lt;computation name="toto"&gt;
  &lt;computation&gt;
    &lt;literal value="7"/&gt;
    &lt;literal value="3"/&gt;
    &lt;add/&gt;
  &lt;/computation&gt;   
 
  &lt;literal value="3"/&gt;
  &lt;multiply/&gt;
&lt;/computation&gt;</pre>

  <p>Much like the use of parentheses in an algebrical equation, the
  presence of a <code>computation</code> element nested in another is
  managed by the <a
  href="../xref/chapters/onJoran/calculator/ComputationAction2.html">
  <code>ComputationAction2</code></a> class using an internal
  stack. The well-formedness of XML will guarantee that a value saved
  by one <code>begin()</code> will be consumed only by the matching
  <code>end()</code> method.</p>
  -->

  <h3 class="doAnchor" name="implicit">Implicit actions</h3>

  <p>The rules defined thus far are called explicit actions because an
  pattern/action association could be found in the rule store for the
  current element. However, in highly extensible systems, the number
  and type of components can be so large so as to make it very tedious
  to associate an explicit action for all patterns.
  </p>

  <p>At the same time, even in highly extensible systems one can
  observe recurrent rules linking various parts together. Assuming we
  could identify such rules, we could process components composed of
  sub-components unknown at compilation time (of logback). For
  example, Apache Ant is capable of handling tasks which contain tags
  unknown at compile time, simply by inspecting the component for
  methods whose names start with <em>add</em>, as in
  <code>addFile</code>, or <code>addClassPath</code>.  When Ant
  encounters an embedded tag within a task, it simply instantiates an
  object that matches the signature of the task class' add method and
  attaches the resulting object to the parent.
  </p>

  <p>Joran supports a similar capability in the form of implicit
  actions. Joran keeps a list of implicit actions which are applied if
  no explicit pattern could match the current pattern.  However,
  applying an implicit action may not be always appropriate. Before
  executing the implicit action, Joran asks a given implicit action
  whether it is appropriate in the current situation. Only if the
  action replies in the affirmative does the Joran configurator invoke
  the (implicit) action. Note that this extra step makes it possible
  to support multiple implicit actions or possibly none, if no
  implicit action is appropriate for a given situation.
  </p>

  <p>You can create and register a custom implicit action as
  illustrated in the next example contained within the
  <em>logback-examples/src/main/java/chapters/onJoran/implicit</em> folder.
  </p>

  <p>The <a
  href="../xref/chapters/onJoran/implicit/PrintMe.html"><code>PrintMe</code></a>
  application associates an <a
  href="../xref/chapters/onJoran/implicit/NOPAction.html">
  <code>NOPAction</code></a> instance with the pattern "*/foo", that
  is any element named as "foo". As its name indicates, the
  <code>begin</code>() and <code>end</code>() methods of
  <code>NOPAction</code> are empty. The <code>PrintMe</code>
  application also registers an instance of <a
  href="../xref/chapters/onJoran/implicit/PrintMeImplicitAction.html">PrintMeImplicitAction</a>
  in its list of implicit actions. The
  <code>PrintMeImplicitAction</code> is applicable for any element
  which has a <span class="attr">printme</span> attribute set to
  true. See the <code>isApplicable()</code> method in
  <code>PrintMeImplicitAction</code>.  The <code>begin()</code>() method
  of <code>PrintMeImplicitAction</code> prints the name of the current
  element on the console.
  </p>

  <p>The XML document <em>implicit1.xml</em> is designed to illustrate
  how implicit actions come into play.</p>

  <em>Example 10.<span class="autoEx"/>: Usage of implicit rules
  (logback-examples/src/main/java/chapters/onJoran/implicit/implicit1.xml)</em>
  <pre class="prettyprint source">&lt;foo&gt;
  &lt;xyz printme="true"&gt;
    &lt;abc printme="true"/&gt;
  &lt;/xyz&gt;

  &lt;xyz/&gt;

  &lt;foo printme="true"/&gt;

&lt;/foo&gt;</pre>

  <p>Running</p>

  <p class="command">java chapters.onJoran.implicit.PrintMe src/main/java/chapters/onJoran/implicit/implicit1.xml</p>
  <p>yields:</p>

  <p class="console">Element [xyz] asked to be printed.
Element [abc] asked to be printed.
20:33:43,750 |-ERROR in c.q.l.c.joran.spi.Interpreter@<b>10:9</b> - no applicable action for [xyz], current pattern is [[foo][xyz]]</p>

  <p>Given that <code>NOPAction</code> instance is explicitly
  associated with the "*/foo" pattern, <code>NOPAction</code>'s
  <code>begin()</code> and <code>end()</code> methods are invoked on
  &lt;foo> elements. <code>PrintMeImplicitAction</code> is never
  triggered for any of the &lt;foo&gt; elements. For other elements,
  since there are no matching explicit actions, the
  <code>isApplicable()</code> method of
  <code>PrintMeImplicitAction</code> is invoked. It will return true
  only for elements having a <span class="attr">printme</span>
  attribute set to true, namely the first &lt;xyz> element (but not
  the second) and the &lt;abc> element. The second &lt;xyz> element on
  line 10, there are no applicable actions, an internal error message
  is generated. This message is printed by the
  <code>StatusPrinter.print</code> invocation, the last statement in
  the <code>PrintMe</code> application. This explains the output shown
  above (see previous paragraph).
  </p>

  <h3 class="doAnchor" name="iaPractice">Implicit actions in
  practice</h3>
  
  <p>The respective Joran configurators of logback-classic and
  logback-access include just two implicit actions, namely <a
  href="../xref/ch/qos/logback/core/joran/action/NestedBasicPropertyIA.html">
  <code>NestedBasicPropertyIA</code></a> and <a
  href="../xref/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.html">
  <code>NestedComplexPropertyIA</code></a>.
  </p>

  <p><code>NestedBasicPropertyIA</code> is applicable for any property
  whose type is a primitive type (or equivalent object type in the
  <code>java.lang</code> package), an enumeration type, or any type
  adhering to the "valueOf" convention.  Such properties are said to
  be <em>basic</em> or <em>simple</em>. A class is said to adhere to
  the "valueOf" convention if it contains a static method named
  <code>valueOf</code>() taking a <code>java.lang.String</code> as
  parameter and returning an instance of the type in question.  At
  present, the <a
  href="../xref/ch/qos/logback/classic/Level.html"><code>Level</code></a>,
  <a
  href="../xref/ch/qos/logback/core/util/Duration.html"><code>Duration</code></a>
  and <a
  href="../xref/ch/qos/logback/core/util/FileSize.html"><code>FileSize</code></a>
  classes follow this convention.
  </p>
  
  <p><code>NestedComplexPropertyIA</code> action is applicable, in the
  remaining cases where <code>NestedBasicPropertyIA</code> is not
  applicable <em>and</em> if the object at the top of the object stack
  has a setter or adder method for a property name equal to the
  current element name. Note that such properties can in turn contain
  other components. Thus, such properties are said to be
  <em>complex</em>.  In presence of a complex property, <a
  href="../xref/ch/qos/logback/core/joran/action/NestedComplexPropertyIA.html">
  <code>NestedComplexPropertyIA</code></a> will instantiate the
  appropriate class for the nested component and attach it to the
  parent component (at the top of the object stack) by using the
  setter/adder method of the parent component and the nested element's
  name. The corresponding class is specified by the <span
  class="attr">class</span> attribute of the (nested) current
  element. However, if the <span class="attr">class</span> attribute
  is missing, the class name can be deduced implicitly, if any of the
  following is true:
  </p>

  <ol>
    <li>there is an internal rule associating the parent object's
    property with a designated class
    </li>
    <li>the setter method contains a @DefaultClass attribute
    designating a given class</li>

    <li>the parameter type of the setter method is a concrete class
    possessing a public constructor
    </li>
  </ol>

  <h4 class="doAnchor" name="defaultClassMapping">Default class
  mapping</h4>

  <p>In logback-classic, there are a handful of internal rules mapping
  parent class/property name pairs to a default class. These are
  listed in the table below.</p>

  <table class="bodyTable">
    <tr>
      <th>Parent class </th>
      <th>property name </th>
      <th>default nested class</th>
    </tr>

    <tr >
      <td>ch.qos.logback.core.AppenderBase</td>
      <td>encoder</td>
      <td>ch.qos.logback.classic.encoder.PatternLayoutEncoder</td>
    </tr>

    <tr class="alt">
      <td>ch.qos.logback.core.UnsynchronizedAppenderBase</td>
      <td>encoder</td>
      <td>ch.qos.logback.classic.encoder.PatternLayoutEncoder</td>
    </tr>

      <tr >
      <td>ch.qos.logback.core.AppenderBase</td>
      <td>layout</td>
      <td>ch.qos.logback.classic.PatternLayout</td>
    </tr>

    <tr class="alt">
      <td>ch.qos.logback.core.UnsynchronizedAppenderBase</td>
      <td>layout</td>
      <td>ch.qos.logback.classic.PatternLayout</td>
    </tr>

    <tr>
      <td>ch.qos.logback.core.filter.EvaluatorFilter</td>
      <td>evaluator</td>
      <td>ch.qos.logback.classic.boolex.JaninoEventEvaluator</td>
    </tr>
  </table>

  <p>This list may change in future releases. Please see
  logback-classic <a
  href="../xref/ch/qos/logback/classic/joran/JoranConfigurator.html">JoranConfigurator</a>'s
  <code>addDefaultNestedComponentRegistryRules</code> method for the
  latest rules.
  </p>

  <p>In logback-access, the rules are very similar. In the default
  class for the nested component, the ch.qos.logback.classic package
  is replaced by ch.qos.logback.access. See logback-access <a
  href="../xref/ch/qos/logback/access/joran/JoranConfigurator.html">JoranConfigurator</a>'s
  <code>addDefaultNestedComponentRegistryRules</code> method for the
  latest rules.
  </p>
  
  <h4 class="doAnchor">Collection of properties</h4>

  
  <p>Note that in addition to single simple properties or single
  complex properties, logback's implicit actions support collections of
  properties, be they simple or complex. Instead of a setter method,
  the property is specified by an "adder" method.</p>

  <h3 class="doAnchor" name="newRule">New rules on the fly</h3>

  <p>Joran includes an action which allows the Joran interpreter to
  learn new rules on the fly, that is while interpreting an XML
  document.  See the
  <em>logback-examples/src/main/java/chapters/onJoran/newRule/</em> directory
  for sample code. In this package, the <a
  href="../xref/chapters/onJoran/newRule/NewRuleCalculator.html">
  <code>NewRuleCalculator</code></a> application sets up just two
  rules, one rule to process the top-most element, and a second rule
  to learn new rules. Here is the relevant code from
  <code>NewRuleCalculator</code>.
  </p>

  <pre class="prettyprint source">ruleMap.put(new Pattern("*/computation"), new ComputationAction1());
<b>ruleStore.addRule(new Pattern("/computation/newRule"), new NewRuleAction());</b></pre>

  <p><a
  href="../xref/ch/qos/logback/core/joran/action/NewRuleAction.html"><code>NewRuleAction</code></a>,
  part of logback-core, works pretty much like the other actions.  It
  has a <code>begin()</code> and <code>end()</code> method, and is
  called each time the parser finds a <em>newRule</em> element. When
  invoked, the <code>begin()</code> method looks for <em>pattern</em>
  and <em>actionClass</em> attributes. It then instantiates the
  corresponding action class and adds the pattern/action association
  as a new rule in Joran's rule store.</p>


  <p>Here is how new rules can be declared in an xml file:</p>

  <pre class="prettyprint source">&lt;newRule pattern="*/computation/literal"
          actionClass="chapters.onJoran.calculator.LiteralAction"/&gt;</pre>

  <p>Using such newRule declarations, we can transform
  <code>NewRuleCalculator</code> to behave like the
  <code>Calculator1</code> application we saw earlier.  involving the
  calculation, could be expressed this way:</p>

  <em>Example 10..<span class="autoEx"/>: Configuration file using new
  rules on the fly
  (logback-examples/src/main/java/chapters/onJoran/newrule/newRule.xml)</em>

  <pre class="prettyprint source">&lt;computation name="toto"&gt;
  &lt;newRule pattern="*/computation/literal" 
            actionClass="chapters.onJoran.calculator.LiteralAction"/&gt;
  &lt;newRule pattern="*/computation/add" 
            actionClass="chapters.onJoran.calculator.AddAction"/&gt;
  &lt;newRule pattern="*/computation/multiply" 
            actionClass="chapters.onJoran.calculator.MultiplyAction"/&gt;

  &lt;computation&gt;
    &lt;literal value="7"/&gt;
    &lt;literal value="3"/&gt;
    &lt;add/&gt;
  &lt;/computation&gt;   
 
  &lt;literal value="3"/&gt;
  &lt;multiply/&gt;
&lt;/computation&gt;</pre>


  <p class="command">java java chapters.onJoran.newRule.NewRuleCalculator src/main/java/chapters/onJoran/newRule/newRule.xml</p>

  <p>yields</p>

  <p class="console">The computation named [toto] resulted in the value 30</p>

  <p>which is identical to the output of the <a
  href="#calculator">original calculator example</a>.</p>


  <script src="../templates/footer.js" type="text/javascript"></script>
</div>
</body>
</html>
